home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 307_01 / disk_io.c < prev    next >
C/C++ Source or Header  |  1990-03-18  |  6KB  |  202 lines

  1. /*=========================================================
  2.  
  3.  TITLE disk_io.c.
  4.  
  5.  This module cotains a functions which interface either
  6.  directly with DOS or BIOS in order to perform disk i/o.
  7.  
  8. ==========================================================*/
  9.  
  10.  
  11. #include <stdio.h>
  12. #include <dos.h>
  13.  
  14. extern union REGS inregs,outregs;
  15. extern int drive,track,sector,head,sect_size;
  16.  
  17. /*-----------------Function Prototypes----------------------*/
  18.  
  19. void    disk_recal(int);
  20. int     disk_reset(void);
  21. int     disk_read(int,int,int,int,char *,int);
  22. int     disk_write(int,int,int,int,char *,int);
  23. int     disk_seek(int,int,int,int);
  24. int     disk_format(int,int,int *,int,int,int,int);
  25. void    disk_test(int,int,int,int);
  26.  
  27. /*----------------------------------------------------------*/
  28.  
  29. /*
  30. ** Declare all disks uninitialised, and init track,sector
  31. ** and head info.
  32. */
  33.  
  34. int disk_reset() {
  35.  
  36.     inregs.h.ah = 0;
  37.     int86(0x13,&inregs,&outregs);
  38.     return outregs.x.ax;
  39.  
  40. }
  41.  
  42. /*
  43. ** Read nsect's into *bufptr.
  44. ** Up to five retries are made if an error occurs.  Register
  45. ** ax returns the error code.
  46. */
  47.  
  48. int disk_read(drv,trk,sect,hd,bufptr,nsect)
  49. int drv,trk,sect,hd,nsect; char *bufptr; {
  50.  
  51. struct SREGS segregs;
  52. int i,j,reg_ax,cflag;
  53. char    far *longptr;
  54.  
  55.     longptr = (char far *)(bufptr);
  56.     for (j = 0; j < nsect; j++) {
  57.         for (i = 2; i > 0; i--) {
  58.             segregs.es  = FP_SEG(longptr);
  59.             inregs.x.bx = FP_OFF(longptr + j * sect_size);
  60.             inregs.h.ah = 2;
  61.             inregs.h.al = 1;                    /* read one sector at a time */
  62.             inregs.h.dl = drv;
  63.             inregs.h.dh = hd;
  64.             inregs.h.ch = trk;
  65.             inregs.h.cl = sect + j;
  66.             int86x(0x13,&inregs,&outregs,&segregs);
  67.             reg_ax = outregs.x.ax;              /* save the status */
  68.             cflag  = outregs.x.cflag;
  69.             if (!cflag) break;                  /*  no error    */
  70.             disk_reset();
  71.             disk_recal(drv);                    /* try to recover the error */
  72.         }
  73.         if (cflag) {
  74.             j = (j ? 0 : j - 1);            /* back up to sector before bad one*/
  75.             disk_seek(drv,trk,sect+j,hd);       /* return to last position */
  76.             break;
  77.         }
  78.     }
  79.     return (!cflag ? 0 : reg_ax);   /* return error in ax */
  80. }
  81. /*
  82.  Write nscet's from *bufptr.
  83.  Up to five retries are made if an error occurs.  Register
  84.  ax returns the error code.
  85. */
  86.  
  87. int disk_write(drv,trk,sect,hd,bufptr,nsect)
  88. int drv,trk,sect,hd,nsect; char *bufptr; {
  89.  
  90. struct SREGS segregs;
  91. int i,j,reg_ax,cflag;
  92. char    far *longptr;
  93.  
  94.     longptr = (char far *)(bufptr);
  95.     for (j = 0; j < nsect; j++) {
  96.         for (i = 2; i > 0; i--) {
  97.             segregs.es  = FP_SEG(longptr);
  98.             inregs.x.bx = FP_OFF(longptr + j * sect_size);
  99.             inregs.h.ah = 3;
  100.             inregs.h.al = 1;            /* write one at a time */
  101.             inregs.h.dl = drv;
  102.             inregs.h.dh = hd;
  103.             inregs.h.ch = trk;
  104.             inregs.h.cl = sect + j;
  105.             int86x(0x13,&inregs,&outregs,&segregs);
  106.             reg_ax = outregs.x.ax;          /* save the status */
  107.             cflag  = outregs.x.cflag;
  108.             if (!outregs.x.cflag) break;
  109.             disk_reset();
  110.             disk_recal(drv);            /* try to recover the error */
  111.         }
  112.         if (cflag) {
  113.             j = (j ? 0 : j - 1);            /* back up to sector before bad one*/
  114.             disk_seek(drv,trk,sect,hd);     /* return to last position */
  115.             break;
  116.         }
  117.     }
  118.     return (!cflag ? 0 : reg_ax);               /* return error in ax */
  119. }
  120.  
  121. /*
  122. ** Seek to track ,sector and head.
  123. */
  124.  
  125. int disk_seek(drv,trk,sect,hd)
  126. int drv,trk,sect,hd; {
  127.  
  128. struct SREGS segregs;
  129. int i,reg_ax;
  130.  
  131.     inregs.h.ah = 4;
  132.     inregs.h.al = 1;
  133.     inregs.h.dl = drv;
  134.     inregs.h.dh = hd;
  135.     inregs.h.ch = trk;
  136.     inregs.h.cl = sect;
  137.     int86x(0x13,&inregs,&outregs,&segregs);
  138.     return (outregs.x.ax);              /* return status */
  139. }
  140. /*
  141. ** Format a track according to the Alien Disk parameters
  142. */
  143.  
  144. int disk_format(fdrive,ftrack,skew,fhead,fbytes,fsect,nsect)
  145. int fdrive, ftrack, *skew, fhead, fbytes,fsect,nsect; {
  146.  
  147. struct SREGS segregs;
  148. int i,reg_ax;
  149. char format_buf[256];
  150. char far *fptr;
  151.  
  152.     fptr = format_buf;
  153.     for (i = fsect; i <= nsect; i++) {  /* build the format table IBM Tech 5-56 */
  154.         *fptr++ = ftrack;
  155.         *fptr++ = fhead;
  156.         *fptr++ = *(skew + i);
  157.         *fptr++ = fbytes;
  158.     }
  159.     fptr = format_buf;
  160.     for (i = 5; i > 0; i--) {
  161.         inregs.x.bx = FP_OFF(fptr);     /* seg:off of format table */
  162.         segregs.es  = FP_SEG(fptr);
  163.         inregs.h.ah = 5;            /* format function */
  164.         inregs.h.dl = fdrive;
  165.         inregs.h.dh = fhead;
  166.         inregs.h.ch = ftrack;
  167.         int86x(0x13,&inregs,&outregs,&segregs);
  168.         if (!outregs.x.cflag) return (0);
  169.         reg_ax = outregs.x.ax;          /* save the status */
  170.         disk_recal(fdrive);         /* try to recover the error */
  171.     }
  172.     return (reg_ax);                /* return error in ax */
  173. }
  174.  
  175. /*
  176. **  A simple Disk Test performing a verify on the sector.
  177. */
  178.  
  179. void disk_test(drv,hd,trk,sect) char drv,hd,trk,sect; {
  180.  
  181.     inregs.h.ah = 4;        /* just verify  */
  182.     inregs.h.al = 1;        /* just read one sector */
  183.     inregs.h.dl = drv;
  184.     inregs.h.dh = hd;
  185.     inregs.h.ch = trk;
  186.     inregs.h.cl = sect;
  187.     int86(0x13,&inregs,&outregs);
  188.  
  189. }
  190.  
  191. void disk_recal(drv) int drv; {
  192.  
  193.     inregs.h.ah = 4;
  194.     inregs.h.al = 1;        /* just read one sector */
  195.     inregs.h.dl = drv;
  196.     inregs.h.dh = 0;
  197.     inregs.h.ch = 0;
  198.     inregs.h.cl = 1;
  199.     int86(0x13,&inregs,&outregs);
  200.  
  201. }
  202.